﻿using System;
using System.Linq;
using Contracts.Entities;
using Model.MovieElements;
using System.Collections.Generic;

namespace Model.Movie
{
    public class WriteMovieItem
    {
        private MovieDatabaseEntities entities;
        private WriteBackdrops writeBackdrops;

        public WriteMovieItem()
        {
            this.entities = new MovieDatabaseEntities();
            this.writeBackdrops = new WriteBackdrops(entities);
        }

        public void Insert(MovieItem item)
        {
            item.Id = GetLastID() + 1;                
            entities.AddToMovies(MovieItemConverter.GetEntity(item));
            entities.SaveChanges();
        }

        public void Update(MovieItem movieItem)
        {
            var movie = entities.Movies.FirstOrDefault(m => m.Id == movieItem.Id);
            WriteMovieElement updateMovieElement;

            if (movie == null)
                return;

            movie.Quality = movieItem.Quality;
            movie.Overview = movieItem.Overview;
            movie.FolderPath = movieItem.FolderPath;
            movie.RuntimeMin = movieItem.RuntimeMin;
            movie.ReleaseYear = movieItem.ReleaseYear;
            movie.FSKAge = movieItem.FskAge;
            movie.Rating = (short)movieItem.Rating;
            movie.TmdbRating = Convert.ToInt16(movieItem.TmdbRating);         
            movie.Revenue = movieItem.Revenue;
            movie.Budget = movieItem.Budget;
            movie.TrailerUrl = movieItem.TrailerUrl;
            movie.Cover = movieItem.Cover;
            movie.Watched = new byte[] {Convert.ToByte(movieItem.Watched)};

            updateMovieElement = new WriteActors(entities, movie);
            updateMovieElement.Process(movieItem.Actors);

            updateMovieElement = new WriteDirectors(entities, movie);
            updateMovieElement.Process(movieItem.Directors);

            updateMovieElement = new WriteGenres(entities, movie);
            updateMovieElement.Process(movieItem.Genres);

            updateMovieElement = new WriteCountries(entities, movie);
            updateMovieElement.Process(movieItem.Countries);

            updateMovieElement = new WriteStudios(entities, movie);
            updateMovieElement.Process(movieItem.Studios);


            entities.SaveChanges();
        }

        public void Delete(MovieItem item)
        {          
            var entity = entities.Movies.First(m => m.Id == item.Id);

            if (entity == null)
                return;

            writeBackdrops.Delete(item.Id);

            DeleteRelations(item.Actors, entity);
            new WriteActors(entities, entity).Update(item.Actors);

            DeleteRelations(item.Directors, entity);
            new WriteDirectors(entities, entity).Update(item.Directors);

            DeleteRelations(item.Genres, entity);
            new WriteGenres(entities, entity).Update(item.Genres);

            DeleteRelations(item.Countries, entity);
            new WriteCountries(entities, entity).Update(item.Countries);

            DeleteRelations(item.Studios, entity);
            new WriteStudios(entities, entity).Update(item.Studios);

            entities.DeleteObject(entity);
            entities.SaveChanges();
        }

        private void DeleteRelations(IEnumerable<MovieElement> items, Movies entity)
        {
            foreach (var relation in items)
                relation.SyncState = SyncState.Deleted;
        }

        private int GetLastID()
        {
            var actor = entities.Movies.OrderByDescending(m => m.Id).FirstOrDefault();
            return actor != null ? actor.Id : 0;
        }
    }
}
